package it.polimi.registration.business.security.entity;

import java.io.Serializable;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.LinkedList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.validation.constraints.NotNull;

@Entity(name = "event")
public class Event implements Serializable, Comparable<Event> {

	private static final long serialVersionUID = 1L;
	
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private int id;
	@NotNull
	private String location;
	
	@Temporal(TemporalType.TIMESTAMP)
	@NotNull
	private Calendar date;
	@NotNull
	private boolean publicc;
	@NotNull
	private boolean outdoor;
	@NotNull
	private String name;
	@NotNull
	private String description;
	
	@OneToOne(cascade = CascadeType.PERSIST)
	private Forecast forecast;

	@OneToOne
	private User owner;
	
	@OneToMany
	private List<User> invitedUsers;

	public Event() {
		this.invitedUsers = new LinkedList<>();
		this.date = new GregorianCalendar();
	}
	
	public Event(User owner) {
		this();
		this.owner = owner;
	}

	public User getOwner() {
		return owner;
	}

	public List<User> getInvitedUsers() {
		return invitedUsers;
	}
	
	public void setInvitedUsers(List<User> invited) {
		this.invitedUsers = invited;
	}

	public Calendar getDate() {
		return date;
	}

	public String getLocation() {
		return location;
	}

	public int getId() {
		return id;
	}

	public String getDescription() {
		return description;
	}
	
	public boolean getPublic() {
		return publicc;
	}

	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public void setLocation(String location) {
		this.location = location;
	}
	
	public void setDescription(String description) {
		this.description = description;
	}
	
	public void setPublic(boolean publicc) {
		this.publicc = publicc;
	}
	
	public void setOutdoor(boolean outdoor) {
		this.outdoor = outdoor;
	}
	
	public boolean getOutdoor() {
		return outdoor;
	}
	
	public void setDate(Calendar date) {
		this.date = date;
	}
	
	public void setDateString(String datestring) {
		//GregorianCalendar(int year, int month, int dayOfMonth, int hourOfDay, int minute) 
		String[] data = datestring.split("[/:-]");
		this.date = new GregorianCalendar(Integer.parseInt(data[2]), Integer.parseInt(data[1])-1, Integer.parseInt(data[0]), Integer.parseInt(data[3]), Integer.parseInt(data[4]));
	}
	
	public String getDateString() {
		return getDay() + "/" +  getMonth() + "/" +  getYear() + "-" +  getHour() + ":" +  getMinute();
	}
	
	public int getDay() {
		return date.get(Calendar.DAY_OF_MONTH);
	}
	
	public int getMonth() {
		return date.get(Calendar.MONTH) + 1;
	}
	
	public String getMonthString() {
		switch(getMonth()) {
			case 1:
				return "Jan";
			case 2:
				return "Feb";
			case 3:
				return "Mar";
			case 4:
				return "Apr";
			case 5:
				return "May";
			case 6:
				return "Jun";
			case 7:
				return "Jul";
			case 8:
				return "Aug";
			case 9:
				return "Sep";
			case 10:
				return "Oct";
			case 11:
				return "Nov";
			case 12:
				return "Dec";
		}
		return "";
	}
	
	public int getYear() {
		return date.get(Calendar.YEAR);
	}
	
	public int getHour() {
		return date.get(Calendar.HOUR_OF_DAY);
	}
	
	public int getMinute() {
		return date.get(Calendar.MINUTE);
	}
	
	public String getPublicString() {
		return getPublic() ? "public" : "private";
	}
	
	public String getOutdoorString() {
		return getOutdoor() ? "outdoor" : "indoor";
	}

	@Override
	public int compareTo(Event arg0) {
		return this.date.compareTo(arg0.getDate());
	}

	public void setForecast(Forecast f) {
		this.forecast = f;
	}
	
	public Forecast getForecast() {
		return forecast;
	}
	
	public boolean getHasForecast() {
		return forecast != null;
	}
	
	@Override
	public boolean equals(Object obj) {
		if(super.equals(obj))
			return true;
		if(!(obj instanceof Event))
			return false;
		
		Event e = (Event) obj;
		return e.getId() == id;
	}
}
